package com.ejiaoyi.common.util;

import com.ejiaoyi.common.enums.TimeFormatter;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * 日期时间工具类
 * 采用 JAVA 8 新特性 LocalDate LocalDateTime LocalTime Instant 进行实现
 *
 * @author unknownChivalrous
 * @since 2020-03-17
 */
public class DateTimeUtil {

    /**
     * 网络时间矫正地址
     */
    private static final String INTERNET_TIME_ADDRESS = "http://www.baidu.com";

    /**
     * 获取网络时间
     *
     * @param timeFormatter 格式化规则
     * @return 时间字符串
     */
    public static String getInternetTime(TimeFormatter timeFormatter) {
        String internetTime = null;

        try {
            URL url = new URL(INTERNET_TIME_ADDRESS);
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();

            long epochMilli = urlConnection.getDate();

            Instant instant = Instant.ofEpochMilli(epochMilli);
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeFormatter.getCode(), Locale.CHINA);
            internetTime = formatter.format(localDateTime);
        } catch (IOException e) {
            internetTime = DateTimeUtil.getNowTime(timeFormatter);
        }

        return internetTime;
    }

    /**
     * 获取当前时间 本地时间
     *
     * @param timeFormatter 格式化规则
     * @return 时间字符串
     */
    private static String getNowTime(TimeFormatter timeFormatter) {
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeFormatter.getCode(), Locale.CHINA);
        return formatter.format(localDateTime);
    }

    /**
     * 返回时间差
     *
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param timeFormatter 格式化方式
     * @return 时间差 seconds
     */
    public static long getTimeDiff(String startTime, String endTime, TimeFormatter timeFormatter) {
        return DateTimeUtil.getTimeDiff(startTime, endTime, TimeUnit.SECONDS, timeFormatter);
    }

    /**
     * 返回时间差
     *
     * @param startTime     开始时间
     * @param endTime       结束时间
     * @param timeUnit      返回时间类型 default mill seconds
     * @param timeFormatter 格式化方式
     * @return 时间差
     */
    public static long getTimeDiff(String startTime, String endTime, TimeUnit timeUnit, TimeFormatter timeFormatter) {
        LocalDateTime start = LocalDateTime.parse(startTime, DateTimeFormatter.ofPattern(timeFormatter.getCode()));
        LocalDateTime end = LocalDateTime.parse(endTime, DateTimeFormatter.ofPattern(timeFormatter.getCode()));
        return DateTimeUtil.getTimeDiff(start, end, timeUnit);
    }

    /**
     * 返回时间差
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 时间差 seconds
     */
    public static long getTimeDiff(LocalDateTime startTime, LocalDateTime endTime) {
        return DateTimeUtil.getTimeDiff(startTime, endTime, TimeUnit.SECONDS);
    }

    /**
     * 返回时间差
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param timeUnit  返回时间类型 default mill seconds
     * @return 时间差
     */
    public static long getTimeDiff(LocalDateTime startTime, LocalDateTime endTime, TimeUnit timeUnit) {
        //计算时间差
        Duration duration = Duration.between(startTime, endTime);

        if (timeUnit == null || timeUnit == TimeUnit.MILLISECONDS) {
            return duration.toMillis();
        }

        switch (timeUnit) {
            case DAYS:
                return duration.toDays();
            case HOURS:
                return duration.toHours();
            case MINUTES:
                return duration.toMinutes();
            case SECONDS:
                return duration.toSeconds();
        }

        return 0L;
    }

    /**
     * 将时间字符串转换为时间戳
     *
     * @param time          时间字符串
     * @param timeFormatter 格式化方式
     * @return 时间戳Long值
     */
    public static Long DateTimeToTimestamp(String time, TimeFormatter timeFormatter) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeFormatter.getCode(), Locale.CHINA);
        LocalDateTime localDateTime = LocalDateTime.parse(time, formatter);
        return localDateTime.toEpochSecond(ZoneOffset.of("+8"));
    }
}
